from flask import (
    Blueprint,
    render_template,
    views,request,
    session,redirect,
    url_for,g,
    jsonify)
from .forms import (
    LoginForm,
    ResetpwdForm,
    ResetemailForm,
    AddBannerForm,
    UpdateBannerForm,
    AddBoardForm,
    UpdateBoardForm)

from .decorators import login_required,permission_required
from .models import CMSUser,CMSPermission
from ..models import BannerModel,BoardModel,PostModel,HighlightPostModel,CommentModel,FirePostModel
from flask_wtf import CSRFProtect
from exts import db,mail
from utils import restful,dxcache
from flask_mail import Message
from threading import Thread
from utils.async import send_async_email
from flask_paginate import Pagination,get_page_parameter
from apps.common.views import handle_time
from tasks import send_mail
import config,os
import string,random

bp = Blueprint('cms',__name__,url_prefix='/cms')

# def send_async_email(msg):
#     mail.send(msg)


@bp.route('/index')
@login_required
def index():
    return render_template('cms/cms_index.html')

#个人中心
@bp.route('/profile/')
@login_required
def profile():
    return render_template('cms/cms_profile.html')

#帖子
@bp.route('/posts/')
@login_required
@permission_required(CMSPermission.POSTER)
def cms_posts():

    page = request.args.get(get_page_parameter(),type=int,default=1)
    start = (page-1)*config.PER_NUM
    end = start + config.PER_NUM
    post_lists = None
    total = 0
    posts = PostModel.query.order_by(PostModel.create_time.desc()).slice(start,end)
    total = PostModel.query.count()
    pagination = Pagination(bs_version=3, page=page,total=total)
    context = {
        'posts':posts,
        'pagination':pagination
    }
    return render_template('cms/cms_posts.html',**context)


#帖子加精
@bp.route('/hpost/',methods=['POST'])
@login_required
@permission_required(CMSPermission.POSTER)
def hpost():
    post_id = request.form.get('post_id')
    print('POST_ID是：',post_id)
    if not post_id:
        return restful.params_error('请传入帖子ID')
    post = PostModel.query.get(post_id)
    if not post:
        return restful.params_error('这篇帖子不存在！')

    highlight = HighlightPostModel()
    highlight.post = post
    db.session.add(highlight)
    db.session.commit()
    return restful.success()
#取消加精
@bp.route('/uhpost/',methods=['POST'])
@login_required
@permission_required(CMSPermission.POSTER)
def uhpost():
    post_id = request.form.get('post_id')
    if not post_id:
        return restful.params_error('请传入帖子ID')
    post = PostModel.query.get(post_id)
    if not post:
        return restful.params_error('这篇帖子不存在！')

    highlight = HighlightPostModel.query.filter(PostModel.id == post_id).first()
    db.session.delete(highlight)
    db.session.commit()
    return restful.success()

# 给帖子加热度
@bp.route('/fpost/',methods=["POST"])
@login_required
@permission_required(CMSPermission.POSTER)
def fpost():
    post_id = request.form.get('post_id')
    if not post_id:
        return restful.params_error('请传入帖子ID')
    post = PostModel.query.get(post_id)
    if not post:
        return restful.params_error('这篇帖子不存在！')

    firelag = FirePostModel()
    firelag.post = post
    db.session.add(firelag)
    db.session.commit()
    return restful.success()


#取消帖子热度
@bp.route('/ufpost/',methods=["POST"])
@login_required
@permission_required(CMSPermission.POSTER)
def ufpost():
    post_id = request.form.get('post_id')
    if not post_id:
        return restful.params_error('请传入帖子ID')
    post = PostModel.query.get(post_id)
    if not post:
        return restful.params_error('这篇帖子不存在！')

    firelag = FirePostModel.query.filter(PostModel.id == post_id).first()
    db.session.delete(firelag)
    db.session.commit()
    return restful.success()



# 帖子删除
@bp.route('/dpost/',methods=['POST'])
@login_required
@permission_required(CMSPermission.POSTER)
def dpost():
    post_id = request.form.get('post_id')
    if not post_id:
        return restful.params_error('请传入帖子ID')
    post = PostModel.query.get(post_id)
    if not post:
        return restful.params_error('这篇帖子不存在！')

    db.session.delete(post)
    db.session.commit()
    return restful.success()

#评论管理
@bp.route('/comments/')
@login_required
@permission_required(CMSPermission.COMMENTER)
def cms_comments():
    page = request.args.get(get_page_parameter(),type=int,default=1)
    start = (page - 1) * 8
    end = start + 8
    comments = CommentModel.query.slice(start, end)
    total = CommentModel.query.count()
    pagination = Pagination(bs_version=3, page=page,total=total)
    context = {
        'comments':comments,
        'pagination1':pagination
    }
    return render_template('cms/cms_comments.html',**context)


#板块显示
@bp.route('/boards/')
@login_required
@permission_required(CMSPermission.BOARDER)
def cms_boards():
    page = request.args.get(get_page_parameter(),type=int,default=1)
    start = (page-1)* config.PER_NUM
    end = start + config.PER_NUM
    boards = BoardModel.query.slice(start,end)
    total = BoardModel.query.count()
    pagination = Pagination(bs_version=3,page=page,total=total)
    content = {
        'boards':boards,
        'pagination2':pagination
    }
    return render_template('cms/cms_boards.html', **content)



#添加板块
@bp.route('/aboard/',methods=['POST'])
@login_required
@permission_required(CMSPermission.BOARDER)
def aboard():
    form = AddBoardForm(request.form)
    if form.validate():
        name = form.name.data
        board = BoardModel(name=name)
        db.session.add(board)
        db.session.commit()
        return restful.success()
    else:
        return restful.params_error(message=form.get_error())


#更新板块，改名字
@bp.route('/uboard/',methods=["POST"])
@login_required
@permission_required(CMSPermission.BOARDER)
def uboard():
    form = UpdateBoardForm(request.form)
    if form.validate():
        board_id = form.board_id.data
        name = form.name.data
        #数据库查找前台传来的board_id ，是否有这个板块
        board = BoardModel.query.get(board_id)
        if board:
            board.name = name
            db.session.commit()
            return restful.success()
        else:
            return restful.params_error('这个板块不存在！')
    else:
        return restful.params_error(message=form.get_error())



#删除板块
@bp.route('/dboard/',methods=["POST"])
@login_required
@permission_required(CMSPermission.BOARDER)
def delboard():
    board_id = request.form.get('board_id')
    if not board_id:
        return restful.params_error('没有这个板块ID')
    board = BoardModel.query.get(board_id)
    if not board:
        return restful.params_error('请重新核对板块名！')
    db.session.delete(board)
    db.session.commit()
    return restful.success()

#前端用户管理
@bp.route('/fusers/')
@login_required
@permission_required(CMSPermission.FRONTUSER)
def cms_fusers():
    return render_template('cms/cms_fusers.html')


@bp.route('/cusers/')
@login_required
@permission_required(CMSPermission.CMSUSER)
def cms_cusers():
    return render_template('cms/cms_cusers.html')


# 轮播图界面
@bp.route('/banners/')
@login_required
def banners():
    banners = BannerModel.query.order_by(BannerModel.priority.desc()).all()
    return render_template('cms/cms_banners.html', banners=banners)


#添加轮播图视图函数
@bp.route('/abanner/',methods=["POST"])
@login_required
def abanner():
    form = AddBannerForm(request.form)
    if form.validate():
        #前台表单得到相应的数据
        name = form.name.data
        image_url = form.image_url.data
        link_url = form.link_url.data
        priority = form.priority.data
        #创建数据库对象，写入数据库
        banner = BannerModel(name=name,image_url=image_url,link_url=link_url,priority=priority)
        db.session.add(banner)
        db.session.commit()
        return restful.success()
    else:
        return restful.params_error(message=form.get_error())


#更新轮播图视图
@bp.route('/ubanner/',methods=['POST'])
@login_required
def ubanner():
    form = UpdateBannerForm(request.form)
    if form.validate():
        #重要的是获取banner_id
        banner_id = form.banner_id.data
        name = form.name.data
        image_url = form.image_url.data
        link_url = form.link_url.data
        priority = form.priority.data
        #在数据库查找这个banner
        banner = BannerModel.query.get(banner_id)
        if not banner:
            return restful.params_error('轮播图不存在！')
        #存在的话，更新数据库里的数据
        banner.name = name
        banner.image_url = image_url
        banner.link_url = link_url
        banner.priority = priority
        db.session.commit()
        return restful.success()
    else:
        return restful.params_error(message=form.get_error())

#删除轮播图
@bp.route('/dbanner/',methods=["POST"])
@login_required
def dbanner():
    banner_id = request.form.get('banner_id')
    if not  banner_id:
        return restful.params_error()
    banner = BannerModel.query.get(banner_id)

    if banner:
        db.session.delete(banner)
        db.session.commit()
        return restful.success()
    else:
        return restful.params_error('没有找到这个轮播图！')

@bp.route('/croles/')
@login_required
@permission_required(CMSPermission.ALL_PERMISSION)
def cms_croles():
    return render_template('cms/cms_croles.html')
class LoginView(views.MethodView):
    def get(self,message=None):
        # print(url_for('cms.resetpwd'))
        return render_template('cms/cms_login.html',message=message)
    def post(self):
        form = LoginForm(request.form)
        if form.validate():
            email = form.email.data
            password = form.password.data
            remember = form.remember.data
            user = CMSUser.query.filter_by(email=email).first()
            if user and user.check_password(password):
                session[config.CMS_USER_ID] = user.id
                if remember:
                    session.permanent = True
                return redirect(url_for('cms.index'))
            else:
                return self.get(message='邮箱或密码错误！')
        else:
            # message = form.errors.popitem()[1][0]
            # return self.get(message=message)
            message = form.get_error()
            return self.get(message=message)


class ResetpwdView(views.MethodView):
    decorators = [login_required]
    def get(self):
        return render_template('cms/cms_resetpwd.html')
    def post(self):
        form = ResetpwdForm(request.form)
        if form.validate():
            oldpwd = form.oldpwd.data
            newpwd = form.newpwd.data
            user = g.cms_user
            if user.check_password(oldpwd):
                user.password = newpwd
                db.session.commit()
                return restful.success()
            else:
                return  restful.params_error('旧密码错误')
        else:
            return restful.params_error(form.get_error())


class ResetemailView(views.MethodView):
    def get(self):
        return render_template('cms/cms_resetmail.html')
    def post(self):
        form = ResetemailForm(request.form)
        if form.validate():
            email = form.email.data
            g.cms_user.email = email
            db.session.commit()
            return restful.success()
        else:
            return restful.params_error(form.get_error())


@bp.route('/email_captcha/')
def email_captcha():
    email = request.args.get('email')
    print(email)
    if not email:
        return restful.params_error('邮箱参数错误！')
    source = list(string.ascii_letters)
    source.extend(map(lambda x:str(x),range(0,10)))
    captcha = ''.join(random.sample(source,4))
    # msg = Message('勤才BBS验证码',recipients=[email],body='你的验证码是%s' % captcha)
    # # try:
    # #     thr = Thread(target=send_async_email, args=[msg])
    # #     thr.start()
    # # except:
    # #     return restful.server_error()
    # # dxcache.set(email,captche)
    # # return restful.success()
    # try:
    #     mail.send(msg)
    # except:
    #     return restful.server_error()
    send_mail.delay('勤才BBS验证码',[email],'你的邮箱验证码是%s' % captcha)
    dxcache.set(email,captcha)
    return restful.success()


@bp.route('/logout/')
@login_required
def logout():
    session.clear()
    return redirect(url_for('cms.login'))


bp.add_url_rule('/login/',view_func=LoginView.as_view('login'))
bp.add_url_rule('/resetpwd/',view_func=ResetpwdView.as_view('resetpwd'))
bp.add_url_rule('/resetemail/',view_func=ResetemailView.as_view('resetemail'))
